package net.lindeer.lang

class Token(val type: Type,
                     val lexeme: String,
                     val literal: Any?,
                     val line: Int) {

    enum class Type {
        // single
        LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE,
        COMMA, DOT, MINUS, PLUS, SEMICOLON, SLASH, STAR,

        // two
        NOT, NOT_EQUAL, EQUAL, EQUAL_EQUAL,
        GREATER, GREATER_EQUAL, LESS, LESS_EQUAL,

        // literals
        IDENTIFIER, STRING, NUMBER,

        // keywords
        AND, CLASS, ELSE, FALSE, FUN, FOR, IF, NULL, OR,
        PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE,

        EOF
    }

    companion object {
        val keywords by lazy {
            listOf(
                    Type.AND,
                    Type.CLASS,
                    Type.ELSE,
                    Type.FALSE,
                    Type.FUN,
                    Type.FOR,
                    Type.IF,
                    Type.NULL,
                    Type.OR,
                    Type.PRINT,
                    Type.RETURN,
                    Type.SUPER,
                    Type.THIS,
                    Type.TRUE,
                    Type.VAR,
                    Type.WHILE
            )
        }
    }

    override fun toString(): String {
        return "$type $lexeme $literal"
    }
}
